<?php
/**
 * Created by PhpStorm.
 * User: meng
 * Date: 2021/7/8
 * Time: 10:21 上午
 */

namespace app\admin\model;


use app\lib\exception\BadRequestException;
use app\lib\exception\ParamsException;
use Exception;
use think\Collection;
use think\db\Query;
use think\facade\Db;
use think\model\concern\SoftDelete;

class AdminRoleModel extends AdminBaseModel
{
    use SoftDelete;
    protected $table = 'admin_role';
    protected $deleteTime = 'delete_time';
    protected $hidden = ['delete_time'];

    protected static $allowedFields = [
        'create' => ['name', 'remarks', 'create_time'],
        'update' => ['name', 'remarks']
    ];

    const NOT_FOUND = 21000;
    const MENU_FAIL = 21003;
    const MEMBER_DEL = 21004;
    const MEMBER_ADD = 21005;
    const DELETE_FAIL = 21006;

    public static function bindMenu ($id, $params) {
        $role = self::findRole($id);
        // 查询出所有存在菜单
        $menusIds = AdminMenuModel::where('id', 'in', $params['menu_ids'])->column('id');
        $saveData = [];
        foreach ($menusIds as $menusId) {
            $saveData[] = ['menu_id' => $menusId, 'role_id' => $role['id']];
        }
        Db::startTrans();
        try {
            // 删除原有绑定菜单
            AdminRoleMenuModel::where('role_id', $role['id'])->delete();
            // 绑定新菜单
            if (!empty($saveData)) {
                $model = new AdminRoleMenuModel();
                $model->saveAll($saveData);
            }
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw new BadRequestException(self::MENU_FAIL);
        }
    }

    public static function roleMenus ($id): Collection {
        $role = self::findRole($id);
        return AdminMenuModel::where('id', 'in', function (Query $query) use ($role) {
            return $query->table('admin_role_menu')->where('role_id', $role['id'])->field('menu_id');
        })->field('id, title, parent_id')->select();
    }

    public static function unbindMembers ($id, $params) {
        $role = self::findRole($id);
        AdminRoleUserModel::where('role_id', $role['id'])
            ->where('user_id', 'in', $params['user_ids'])
            ->delete();
    }

    public static function bindMembers ($id, $params) {
        $role = self::findRole($id);
        $saveData = [];
        $userIds = AdminRoleUserModel::where('role_id', $id)
            ->where('user_id', 'in', $params['user_ids'])
            ->select()->toArray();
        foreach ($params['user_ids'] as $v) {
            if (!in_array(intval($v), $userIds)) {
                $saveData[] = ['user_id' => $v, 'role_id' => $role['id']];
            }
        }
        if (!empty($saveData)) {
            $model = new AdminRoleUserModel;
            $model->saveAll($saveData);
        }
    }

    public static function memberList ($id, $params): array {
        $role = self::findRole($id);
        $members = AdminUserModel::where('id', 'in', function (Query $query) use ($id) {
            $query->table('admin_role_user')->where('role_id', $id)->field('user_id');
        })->where(AdminUserModel::queryWhere($params))
            ->order(self::querySort($params))
            ->paginate(self::queryLimit($params))
            ->toArray();
        $members['role'] = $role;
        return $members;
    }

    public static function createRole ($params) {
        self::create($params, self::$allowedFields['create']);
    }

    public static function updateRole ($id, $params) {
        $role = self::findRole($id);
        $role->allowField(self::$allowedFields['update'])->save($params);
    }

    public static function deleteRole ($id) {
        // 删除角色
        $role = self::findRole($id);
        if ($role['id'] === 1) {
            throw new ParamsException('超级管理员不能删除');
        }
        Db::startTrans();
        try {
            $role->delete();
            // 删除菜单角色
            AdminRoleMenuModel::where('role_id', $id)->delete();
            // 删除用户角色
            AdminRoleUserModel::where('role_id', $id)->delete();
            Db::commit();
        } catch (Exception $e) {
            Db::rollback();
            throw new BadRequestException(self::DELETE_FAIL);
        }
    }

    public static function roleList ($params): array {
        return self::where(self::queryWhere($params))->order(self::querySort($params))->paginate(self::queryLimit($params))->toArray();
    }

    public static function findRole ($id) {
        $data = self::find($id);
        if (empty($data)) {
            throw new BadRequestException(self::NOT_FOUND);
        }
        return $data;
    }

    private static function queryWhere ($params): array {
        $where = [];
        if (!empty($params['keyword']) && trim($params['keyword'])) {
            $where[] = ['name', 'like', '%' . trim($params['keyword']) . '%'];
        }
        return $where;
    }
}
